package com.sfx.concurrent.demo.concurrent.BlockingQueue;

import lombok.extern.slf4j.Slf4j;

import java.util.HashSet;
import java.util.concurrent.TimeUnit;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: sfx
 * Date: 2023-01-22
 * Time: 19:32
 */
@Slf4j(topic = "c.MyThreadPool")
public class MyThreadPool {

    //任务队列
    private MyBlockingQueue<Runnable> taskQueue;

    //线程的集合
    private HashSet<Worker> workers = new HashSet<>();

    //核心线程数
    private int coreSize;

    //设置获取任务的超时时间
    private long timeout;
    private TimeUnit unit;

    public MyThreadPool(int coreSize, long timeout, TimeUnit unit,int queueCapacity) {
        this.coreSize = coreSize;
        this.timeout = timeout;
        this.unit = unit;
        taskQueue = new MyBlockingQueue<>(queueCapacity);
    }

    //执行任务的方法
    public void execute(Runnable task) {
        //当线程集合数<线程核心数,就需要创建任务对象来执行此任务->交给worker来执行
        if(workers.size() < this.coreSize) {
            Worker worker = new Worker(task);
            log.debug("新增worker{},{}",worker,task);
            workers.add(worker);
            worker.start();
        }else {
            //如果线程集合数量超过了线程核心数,那么就将任务放到队列中
            log.debug("加入到任务队列");
            taskQueue.put(task);
        }
    }

    //任务对象来执行次任务
    class Worker extends Thread{
        private Runnable task;

        public Worker(Runnable task) {
            this.task = task;
        }
        //该Works执行该任务
        @Override
        public void run() {
            //因为该任务对象要不断地执行任务
            //1.当有任务就执行->task!=null
            //2.没有任务去看任务队列是否为空,从任务队列中取出任务执行
            while(task!=null || (task = taskQueue.take())!=null) {
                try{
                    log.debug("正在执行...");
                    task.run();
                }catch (Exception e) {
                    e.printStackTrace();

                }finally {
                    task = null;
                }
            }
            //当该任务对象执行完任务了,那就需要从线程(任务对象)集合中移除
            synchronized (workers) {
                log.debug("worker被移除{}",this);
                workers.remove(this);
            }
        }
    }
}